from asyncore import dispatcher
from tkinter import N
from typing import Any, Text, Dict, List
from datetime import datetime, timedelta
from rasa_sdk import Action, Tracker
from rasa_sdk.executor import CollectingDispatcher
from rasa_sdk.events import EventType
from typeguard import check_dict
from database import Department, Disease, Symptom
from py2neo import Graph


class ActionQueryTime(Action):
    def name(self) -> Text:
        return "action_query_time"

    def run(
        self,
        dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: Dict[Text, Any],
    ) -> List[Dict[Text, Any]]:

        current_time = datetime.now().strftime("%H:%M:%S")
        dispatcher.utter_message(text=current_time)

        return []


class ActionQueryHospital(Action):
    """查询疾病对应医院"""
    def name(self) -> Text:
        return "action_query_hospital"

    def run(
        self,
        dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: Dict[Text, Any],
    ) -> List[Dict[Text, Any]]:
        g = Graph(password='neo4j')
        disease_name = tracker.get_slot('disease')
        dis = Disease.match(g).where(name=disease_name).first()
        drugs = [d.name for d in dis.drugs]
        drugs = drugs if len(drugs) <10 else drugs[:10]
        text = f'治疗{disease_name}可以服用如下药物: \n'
        for d in drugs:
            s = '- ' + d + '\n'
            text += s

        return []

class ActionQueryMedicine(Action):
    """查询疾病对应药物"""
    def name(self) -> Text:
        return "action_query_medicine"

    def run(
        self,
        dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: Dict[Text, Any],
    ) -> List[Dict[Text, Any]]:

        g = Graph(password='neo4j')
        disease_name = tracker.get_slot('disease')
        dis = Disease.match(g).where(name=disease_name).first()
        drugs = [d.name for d in dis.drugs]
        drugs = drugs if len(drugs) <10 else drugs[:10]
        text = f'治疗{disease_name}可以服用如下药物: \n'
        for d in drugs:
            s = '- ' + d + '\n'
            text += s
        dispatcher.utter_message(text=text)

        return []

class ActionQueryDepartment(Action):
    """查询疾病对应科室"""
    def name(self) -> Text:
        return "action_query_department"

    def run(
        self,
        dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: Dict[Text, Any],
    ) -> List[Dict[Text, Any]]:
        g = Graph(password='neo4j')
        disease_name = tracker.get_slot('disease')
        dis = Disease.match(g).where(name=disease_name).first()
        departs = [d.name for d in dis.departs]
        departs = departs if len(departs) <10 else departs[:10]
        text = f'治疗{disease_name}到如下科室: \n'
        for d in departs:
            s = '- ' + d + '\n'
            text += s
        dispatcher.utter_message(text=text)
        return []

class ActionQueryFood(Action):
    """查询疾病对应科室"""
    def name(self) -> Text:
        return "action_query_food"

    def run(
        self,
        dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: Dict[Text, Any],
    ) -> List[Dict[Text, Any]]:
        g = Graph(password='neo4j')
        disease_name = tracker.get_slot('disease')
        dis = Disease.match(g).where(name=disease_name).first()
        foods = [d.name for d in dis.foods]
        foods = foods if len(foods) <10 else foods[:10]
        text = f'治疗{disease_name}可以宜吃下列食物: \n' + '\n'.join(foods)
        dispatcher.utter_message(text=text)
        return []


class ActionAskSymptom(Action):
    def name(self) -> Text:
        return "action_ask_symptom"

    def run(
        self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict
    ) -> List[EventType]:
        dispatcher.utter_message(text="What cuisine?")
        return []
    
class ActionDiagnose(Action):
    def name(self) -> Text:
        return "action_diagnose"
    
    def run(self,
            dispatcher: CollectingDispatcher,
            tracker: Tracker,
            domain: Dict) -> List[EventType]:
        g = Graph(password='neo4j')
        symptoms: List = tracker.get_slot('symptoms')
        checked_syms = []
        set_dis = set()
        for s in symptoms:
            try:
                sym = Symptom.match(g).where(name='流鼻涕').first()
                if sym is not None:
                    checked_syms.append(sym.name)
                dis = set(d.name for d in sym.diseases)
                if len(set_dis) == 0:
                    set_dis = set_dis | dis
                else:
                    set_dis = set_dis & dis
            except Exception:
                pass 
        
        if len(set_dis) == 0:
            dispatcher.utter_message(text="没有找到疾病")
        else:
            sym_text = '*' + '*'.join(checked_syms) + '*'
            text = f'根据您的症状 {sym_text} 找到如下疾病: \n' +  '\n'.join(list(set_dis)[:5])
            dispatcher.utter_message(text=text)
        return []






